#include "fig_tool_bone_producer.h"

#include "script/write_lua.h"
#include "script/scripthelper.h"

#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros

using namespace script;

FIGToolBoneProducer::FIGToolBoneProducer() : m_CurrentStepID(0)
{
	//return;
	
	ReadFile("transform/miniboss_hulk/miniboss_hulk_0.lua");
	ReadFile("transform/miniboss_hulk/miniboss_hulk_1.lua");
	ReadFile("transform/miniboss_hulk/miniboss_hulk_2.lua");
	Export("transform/miniboss_hulk.lua");

	ReadFile("transform/miniboss_cobra/miniboss_cobra_step_0.lua");
	ReadFile("transform/miniboss_cobra/miniboss_cobra_step_1.lua");
	ReadFile("transform/miniboss_cobra/miniboss_cobra_step_2.lua");
	Export("transform/miniboss_cobra.lua");

	ReadFile("transform/miniboss_triangle/miniboss_triangle_0.lua");
	ReadFile("transform/miniboss_triangle/miniboss_triangle_1.lua");
	ReadFile("transform/miniboss_triangle/miniboss_triangle_2.lua");
	Export("transform/miniboss_triangle.lua");

	ReadFile("transform/boss_beast/boss_beast_step_0.lua");
	ReadFile("transform/boss_beast/boss_beast_step_1.lua");
	ReadFile("transform/boss_beast/boss_beast_step_2.lua");
	ReadFile("transform/boss_beast/boss_beast_step_3.lua");
	ReadFile("transform/boss_beast/boss_beast_step_4.lua");
	ReadFile("transform/boss_beast/boss_beast_step_5.lua");
	ReadFile("transform/boss_beast/boss_beast_step_6.lua");	
	ReadFile("transform/boss_beast/boss_beast_step_7.lua");	
	ReadFile("transform/boss_beast/boss_beast_step_8.lua");	
	Export("transform/boss_beast.lua");

	ReadFile("transform/boss_hummer/boss_hummer_step_0.lua");
	ReadFile("transform/boss_hummer/boss_hummer_step_1.lua");
	ReadFile("transform/boss_hummer/boss_hummer_step_2.lua");
	ReadFile("transform/boss_hummer/boss_hummer_step_3.lua");
	ReadFile("transform/boss_hummer/boss_hummer_step_4.lua");
	ReadFile("transform/boss_hummer/boss_hummer_step_5.lua");	   
	ReadFile("transform/boss_hummer/boss_hummer_step_6.lua");	   
	ReadFile("transform/boss_hummer/boss_hummer_step_7.lua");	   	
	Export("transform/boss_hummer.lua");

	ReadFile("transform/boss_boffer/boss_boffer_step_0.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_1.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_2.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_3.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_4.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_5.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_6.lua");	   
	ReadFile("transform/boss_boffer/boss_boffer_step_7.lua");	   
	Export("transform/boss_boffer.lua");

	ReadFile("transform/boss_destoryer/boss_destoryer_step_0.lua");	   
	ReadFile("transform/boss_destoryer/boss_destoryer_step_1.lua");	   
	ReadFile("transform/boss_destoryer/boss_destoryer_step_2.lua");
	ReadFile("transform/boss_destoryer/boss_destoryer_step_3.lua");
	ReadFile("transform/boss_destoryer/boss_destoryer_step_4.lua");
	ReadFile("transform/boss_destoryer/boss_destoryer_step_5.lua");
	ReadFile("transform/boss_destoryer/boss_destoryer_step_6.lua");
		
	Export("transform/boss_destoryer.lua");

	//ReadFile("transform/boss_electro/boss_electro_step_0.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_1.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_2.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_3.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_4.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_5.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_6.lua");	   
	//ReadFile("transform/boss_electro/boss_electro_step_7.lua");	   
	//Export("transform/boss_electro.lua");

	//ReadFile("transform/boss_eye/boss_eye_step_0.lua");	   
	//Export("transform/boss_eye.lua");

	//ReadFile("transform/boss_mega/boss_mega_step_0.lua");	   
	//Export("transform/boss_mega.lua");

	//ReadFile("transform/boss_pyro/boss_pyro_step_0.lua");	   
	//ReadFile("transform/boss_pyro/boss_pyro_step_1.lua");	   
	//ReadFile("transform/boss_pyro/boss_pyro_step_2.lua");	   
	//ReadFile("transform/boss_pyro/boss_pyro_step_3.lua");	   
	//ReadFile("transform/boss_pyro/boss_pyro_step_4.lua");	   
	//ReadFile("transform/boss_pyro/boss_pyro_step_5.lua");	   
	//ReadFile("transform/boss_pyro/boss_pyro_step_6.lua");	   
	//Export("transform/boss_pyro.lua");

	//ReadFile("transform/boss_viper/boss_viper_step_0.lua");	   
	//Export("transform/boss_viper.lua");

	ReadFile("transform/boss_gyver/boss_gyver_step_0.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_1.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_2.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_3.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_4.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_5.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_6.lua");	   
	ReadFile("transform/boss_gyver/boss_gyver_step_7.lua");	   
	Export("transform/boss_gyver.lua");

	//ReadFile("transform/boss_monster/boss_monster_step_0.lua");	   
	//Export("transform/boss_monster.lua");

	ReadFile("transform/boss_eagle/boss_eagle_step_0.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_1.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_2.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_3.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_4.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_5.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_6.lua");	   
	ReadFile("transform/boss_eagle/boss_eagle_step_7.lua");	   
	Export("transform/boss_eagle.lua");

	ReadFile("transform/boss_u14/boss_u14_step_0.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_1.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_2.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_3.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_4.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_5.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_6.lua");	   
	ReadFile("transform/boss_u14/boss_u14_step_7.lua");	
	Export("transform/boss_u14.lua");

		
	ReadFile("transform/machinegun/machinegun_step_0.lua");	   
	ReadFile("transform/machinegun/machinegun_step_1.lua");	   
	ReadFile("transform/machinegun/machinegun_step_2.lua");	   
	Export("transform/weapon_machinegun.lua");

	ReadFile("transform/lasergun/lasergun_step_0.lua");	   
	ReadFile("transform/lasergun/lasergun_step_1.lua");	   
	Export("transform/weapon_lasergun.lua");

	ReadFile("transform/shotgun/shotgun_step_0.lua");	   
	ReadFile("transform/shotgun/shotgun_step_1.lua");	   
	Export("transform/weapon_shotgun.lua");

	ReadFile("transform/miniboss_meganito/miniboss_meganito_step_0.lua");	   
	ReadFile("transform/miniboss_meganito/miniboss_meganito_step_1.lua");	   
	Export("transform/miniboss_meganito.lua");

	ReadFile("transform/miniboss_fox/miniboss_fox_step_0.lua");	   
	ReadFile("transform/miniboss_fox/miniboss_fox_step_1.lua");	   
	ReadFile("transform/miniboss_fox/miniboss_fox_step_2.lua");	   
	ReadFile("transform/miniboss_fox/miniboss_fox_step_3.lua");	   
	Export("transform/miniboss_fox.lua");

	ReadFile("transform/miniboss_pron/miniboss_pron_step_0.lua");	   
	ReadFile("transform/miniboss_pron/miniboss_pron_step_1.lua");	   
	ReadFile("transform/miniboss_pron/miniboss_pron_step_2.lua");	   
	Export("transform/miniboss_pron.lua");
						   
	ReadFile("transform/miniboss_plato/miniboss_plato_step_0.lua");
	ReadFile("transform/miniboss_plato/miniboss_plato_step_1.lua");
	Export("transform/miniboss_plato.lua");

	ReadFile("transform/miniboss_shark/miniboss_shark_step_0.lua");
	ReadFile("transform/miniboss_shark/miniboss_shark_step_1.lua");
	Export("transform/miniboss_shark.lua");

	ReadFile("transform/miniboss_hadiez/miniboss_hadiez_step_0.lua");
	ReadFile("transform/miniboss_hadiez/miniboss_hadiez_step_1.lua");
	ReadFile("transform/miniboss_hadiez/miniboss_hadiez_step_2.lua");
	ReadFile("transform/miniboss_hadiez/miniboss_hadiez_step_3.lua");
	Export("transform/miniboss_hadiez.lua");

	ReadFile("transform/miniboss_bomber/miniboss_bomber_step_0.lua");
	ReadFile("transform/miniboss_bomber/miniboss_bomber_step_1.lua");
	Export("transform/miniboss_bomber.lua");

	ReadFile("transform/miniboss_wolf/miniboss_wolf_step_0.lua");
	ReadFile("transform/miniboss_wolf/miniboss_wolf_step_1.lua");
	Export("transform/miniboss_wolf.lua");
	

	ReadFile("transform/title/title_1.lua");
	ReadFile("transform/title/title_2.lua");
	ReadFile("transform/title/title_3.lua");
	ReadFile("transform/title/title_4.lua");
	Export("transform/title.lua");


	// call last
	ExportFileList();
}

FIGToolBoneProducer::~FIGToolBoneProducer()
{
	Clear();
}

void	FIGToolBoneProducer::Clear()
{
	for(int i =0; i < (int)m_Animation.size(); i++)
	{
		FIGToolBoneProducer::StepTable* pStepTable = m_Animation[i];
		for(int j =0; j < (int)pStepTable->m_PartTables.size() ; j++)
		{
			FIGToolBoneProducer::PartTable* pPartTable = pStepTable->m_PartTables[j];
			UTIL_SAFE_DELETE(pPartTable);
		}
		pStepTable->m_PartTables.resize(0);

		UTIL_SAFE_DELETE(pStepTable);
	}

	for(int i =0; i < (int)m_WayPoints.size(); i++)
	{
		UTIL_SAFE_DELETE(m_WayPoints[i]);
	}
	m_WayPoints.resize(0);
	m_Animation.resize(0);
	m_BoneTable.resize(0);
	m_CurrentStepID = 0;
}

void	FIGToolBoneProducer::ReadFile(const std::string& FileName)
{
	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	{
		if (!ScriptHelper::DoFile(*pScript, FileName))
		{
			LuaPlus::LuaState::Destroy( pScript );
			return;
		} 	
		
		FIGToolBoneProducer::StepTable* pStepTable = new FIGToolBoneProducer::StepTable();
		LuaPlus::LuaObject BoneTable = pScript->GetGlobal("LevelInfo");
		for(int i =0; i <BoneTable.GetTableCount(); i++)
		{
			LuaPlus::LuaObject Obj = BoneTable.GetByIndex(i+1);

			std::string BoneName = ScriptHelper::GetTableString(Obj,"Name"); 
			float Rotation  = ScriptHelper::GetTableFloat(Obj,"Rotation"); 
			float CenterRelativeX  = ScriptHelper::GetTableFloat(Obj,"CenterRelativeX"); 
			float CenterRelativeY  = ScriptHelper::GetTableFloat(Obj,"CenterRelativeY"); 
	      	
			if(!BoneName.empty())
			{
				int ID = AddToBoneTable(BoneName);
				FIGToolBoneProducer::PartTable* pPartTable = new FIGToolBoneProducer::PartTable();
				pPartTable->m_CenterRelative = math::Vec2(CenterRelativeX,CenterRelativeY);
				pPartTable->m_ID =	ID;
				pPartTable->m_Rotation = Rotation;
				pStepTable->m_PartTables.push_back(pPartTable);
						
			}

		}
		

		pStepTable->StepID = m_CurrentStepID;
		m_CurrentStepID++;
		m_Animation.push_back(pStepTable);


		//-----------------

		LuaPlus::LuaObject WPTable = pScript->GetGlobal("WayPoints");
		for(int i =0; i <WPTable.GetTableCount(); i++)
		{
			LuaPlus::LuaObject Obj = WPTable.GetByIndex(i+1);
			int ID = ScriptHelper::GetTableInt(Obj,"ID"); 
			math::Vec2 Center = ScriptHelper::GetTableVec2(Obj,"Center"); 

			FIGToolBoneProducer::WayPoint* pWP = new FIGToolBoneProducer::WayPoint();
			pWP->m_ID = ID;
			pWP->m_Pos = Center - math::Vec2(0.5f,0.5f);
			m_WayPoints.push_back(pWP);
		}

	}

	LuaPlus::LuaState::Destroy( pScript );
}


void	FIGToolBoneProducer::ExportFileList()
{
	if(m_BoneFileNames.size() == 0)
		return;

	WriteLua	wl;		

	if (!wl.Open("transform/bonefilelist.lua")) return;		

	wl.StartTable("BoneFiles");
		for(int i = 0; i < (int)m_BoneFileNames.size(); i++)
		{
			wl.StartTable();
			wl.WritePair("Name", m_BoneFileNames[i]);			
			wl.WritePair("Index", i);			
			wl.CloseTable();
		}

	wl.CloseTable(false);

}

void	FIGToolBoneProducer::Export(const std::string& Name)
{
	
	m_BoneFileNames.push_back(Name);
	if (Name.size() > 3)
	{
		WriteLua	wl;		

		if (!wl.Open(Name)) return;		

		wl.StartTable("Bones");
		
		for(int i = 0; i < (int)m_BoneTable.size(); i++)
		{
			wl.StartTable();
			wl.WritePair("ID", i);
			wl.WritePair("Name", m_BoneTable[i]);
			wl.CloseTable();

		}
		wl.CloseTable(false);

		//--------------

		wl.StartTable("Animation");

		for(int i =0; i < (int)m_Animation.size(); i++)
		{
			wl.StartTable();

			FIGToolBoneProducer::StepTable* pStepTable = m_Animation[i];
			wl.WritePair("StepID", pStepTable->StepID);
			wl.WritePair("Duration", pStepTable->Duration);

				wl.StartTable("Parts");
					for(int j =0; j < (int)pStepTable->m_PartTables.size() ; j++)
					{
						 FIGToolBoneProducer::PartTable* pPartTable = pStepTable->m_PartTables[j];
						 wl.StartTable();
						 wl.WritePair("ID", pPartTable->m_ID);

						 while(pPartTable->m_Rotation < 0)
							pPartTable->m_Rotation += 360.0f;
						 wl.WritePair("Rotation", pPartTable->m_Rotation);

						 wl.WritePair("CenterRelative", pPartTable->m_CenterRelative);
						 wl.CloseTable();
					}
				wl.CloseTable();

			wl.CloseTable();
		}

		wl.CloseTable(false);

		//--------------

		//--------------

		wl.StartTable("WayPoint");

		for(int j =0; j < (int)m_WayPoints.size() ; j++)
		{
		    wl.StartTable();
				wl.WritePair("ID", m_WayPoints[j]->m_ID);
				wl.WritePair("Pos", m_WayPoints[j]->m_Pos);
		    wl.CloseTable();
		}

		wl.CloseTable(false);
		
	}

	Clear();
}


int	FIGToolBoneProducer::AddToBoneTable(const std::string& Name)
{
	for(int i = 0 ; i < (int)m_BoneTable.size(); i++)
	{
		std::string BoneName = m_BoneTable[i];
		if(BoneName.compare(Name) == 0)
			return i;
	}

	m_BoneTable.push_back(Name);
	return (int)m_BoneTable.size() - 1;
}